Playwright vs. Cypress: Why Testing Concepts Matter More Than Tools

The debate between Playwright and Cypress fans shows no signs of cooling down. Both tools have their strengths, but the real question is: should you invest time mastering a tool, or should you focus on the fundamental concepts of testing?

If you understand the core principles—test isolation, assertions, handling flaky tests, and waiting strategies—you can easily transition between tools. Let's explore some key testing concepts and how they translate across Cypress and Playwright.

Test Isolation and Reliable State Management A solid test should not depend on previous test runs. Both Cypress and Playwright provide ways to ensure isolation:

Cypress

beforeEach(() => {
  cy.visit('/login');
  cy.get('#username').type('testuser');
  cy.get('#password').type('password');
  cy.get('button[type="submit"]').click();
});

Playwright

test.beforeEach(async ({ page }) => {
  await page.goto('/login');
  await page.fill('#username', 'testuser');
  await page.fill('#password', 'password');
  await page.click('button[type="submit"]');
});

The concept here is ensuring each test starts from a clean state, whether it's resetting the database or reloading the application. Both offer global setup and teardown options to prepare and clean up the test environment.

Cypress In Cypress it is possible to define certain actions in the cypress.conf or even in the command.ts file

// cypress.conf.ts
module.exports = {
  e2e: {
    setupNodeEvents(on, config) {
      on('before:run', () => {
        // Global setup (e.g., initialize DB)
      });
      
      on('after:run', () => {
        // Global teardown (e.g., clean up data)
      });
    },
  },
};

// commands.ts
Cypress.on('after:run', () => {
  databaseInteraction('purge');
});

Playwright In playwright, you can add reference to scripts in order to trigger the setup or teardown.

// playwright.config.js
module.exports = {
  globalSetup: require.resolve('./global-setup'),
  globalTeardown: require.resolve('./global-teardown'),
};

Assertions: Validating Expected Outcomes Assertions confirm that our application behaves as expected. Both Cypress and Playwright offer built-in assertion mechanisms.

Cypress

cy.get('.welcome-message').should('contain', 'Welcome, testuser');

Playwright

await expect(page.locator('.welcome-message')).toContainText('Welcome, testuser');

Different syntax, but the concept remains the same—validating expected behavior.

Handling Flaky Tests with Proper Waiting Strategies A common pitfall in UI testing is dealing with elements that load asynchronously. Proper waiting strategies prevent flaky tests.

Cypress (Automatic retrying)

cy.get('.notification').should('be.visible');

Playwright (Explicit waiting)

await page.waitForSelector('.notification', { state: 'visible' });

While Cypress automatically retries commands for a certain amount of time, Playwright offers more explicit control over waiting behavior. Understanding how and when to wait for elements is crucial. Here the tools differ in execution, but the concept remains the same. A good waiting strategy is vital for a strong test framework.

API Mocking: Controlling Test Data Both tools support API mocking, which is essential for avoiding unreliable network calls during testing.

Cypress

cy.intercept('GET', '/api/user', { fixture: 'user.json' }).as('getUser');
cy.wait('@getUser');

Playwright

await page.route('**/api/user', async (route) => {
  await route.fulfill({ body: JSON.stringify({ name: 'testuser' }) });
});

Mocking API responses ensures tests run quickly and predictably, regardless of network conditions.

Conclusion: Master the Concepts, Not Just the Tool Cypress and Playwright have different learning curves, but the underlying testing concepts remain the same. If you focus on mastering these principles, switching tools becomes a minor adjustment rather than a complete overhaul.

Instead of arguing about which tool is better, let’s invest in learning the strategies that make UI testing reliable, efficient, and maintainable. The tools will follow.